#! /usr/bin/python2.7

# utility to establish APN connection via CNICE

import os, os.path, sys, time, select, signal, json

PPS_CNICE_CONTROLLER = "/pps/services/cds/cnice/control?wait";
PPS_CNICE_STATUS = "/pps/services/cds/cnice/status?wait";
PPS_ID = "connect.py";

gExit = False;

def connect(logicalName, retries):
	connId = "";
	result = False;
	fd = os.open(PPS_CNICE_CONTROLLER, os.O_RDWR);
	request = "msg::connect\n";
	request = request + "id::" + PPS_ID + "\n";
	request = request + "dat:json:{\"name\":\"" + logicalName + "\", \"retries\":" + retries + "}\n";
	print "REQ \n{0}".format( request );
	
	os.write(fd, request);
	response = os.read(fd, 4 * 1024);
	print "RESP \n{0}".format (response );
	
	for line in response.split("\n"):
		if len(line) > 0:
			if line.startswith("dat:json:"):
				decoder = json.JSONDecoder();
				attribs = decoder.decode(line[len("dat:json:"):]);
				if "connect_id" in attribs:
					connId = attribs["connect_id"];
					result = True;
				if "already_connected" in attribs:
					result = attribs["already_connected"];
			elif line.startswith("err:n:"):
				connId = "";
				result = False;
				print "Failed to connect with cause {0}\n".format( line[len("err:n:"):] );
	os.close(fd);
	return (result, connId);

def disconnect(connId, logicalName, force):
	fd = os.open(PPS_CNICE_CONTROLLER, os.O_RDWR);
	request = "msg::disconnect\n";
	request = request + "id::" + PPS_ID + "\n";
	request = request + "dat:json:{\"name\":\"" + logicalName + "\",\"connect_id\":\"" + connId + "\",\"force\":" + force + "}\n";
	print "REQ \n{0}".format( request );
	
	os.write(fd, request);
	response = os.read(fd, 4 * 1024);
	print "RESP \n{0}".format (response );
	os.close(fd);
	
def connectionstatus_wait():
	fd_status = os.open(PPS_CNICE_STATUS, os.O_RDONLY);
	poller = select.poll();
	poller.register(fd_status, select.POLLIN);
	global gExit;
	while not gExit:
		try:
			for fd, event in poller.poll(500):		
				status = os.read(fd, 4 * 1024);
				print status;
		except:
			pass;
			
	os.close(fd_status);
	
def on_term(signum, frame):
	print "signal {0} received.\n".format( signum );
	global gExit;
	gExit = True;
		
def main():
	if len(sys.argv) < 2:
		print "Please provide APN logical name.";
		return;
	
	force = "false";
	
	signal.signal(signal.SIGTERM, on_term);
	signal.signal(signal.SIGINT, on_term);
	
	logicalName = sys.argv[1].lower();
	
	retries = "-1";
	if len(sys.argv) > 2:
		retries = sys.argv[2];
	
	(result, connId) = connect(logicalName, retries);
	if not result:
		print "can not connect to {0} {1}\n".format( logicalName, retries );
		return;
		
	if len(connId) == 0:
		print "no connId returned\n";
		return;
	
	if len(sys.argv) == 4:
		force = sys.argv[3].lower();
	
	connectionstatus_wait();
	disconnect(connId, logicalName, force);
		
if __name__ == "__main__":
	main();